package message;

import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.RandomUtils;
import serialport.SerialPortData;
import serialport.SerialPortError;
import serialport.SerialPortException;

import java.util.*;
import java.util.stream.Collectors;

public class ReceiveUpload extends SerialPortData {
    List<Pinboard> pinboards = new ArrayList<Pinboard>();
    List<Powerbank> powerbanks = new ArrayList<Powerbank>();
    List<SerialPort> serialPortList = new ArrayList<SerialPort>();

    public List<Pinboard> getPinboards() {
        return pinboards;
    }

    public List<Powerbank> getPowerbanks() {
        return powerbanks;
    }

    public ReceiveUpload(byte[] bytes) throws SerialPortException {
        super(bytes);
        if(super.getCmd() != 0X10){
            throw new SerialPortException(SerialPortError.CMD);
        }

        int hole = getHole(bytes);
        int[] data = getData();

        //机芯数据81 = 转接板6 + （充电宝15） * 5
        int pinboardAndPowerbank = (hole * 15 + 6);
        int pinboardCount = data.length / pinboardAndPowerbank;

        for(int i = 0; i < pinboardCount; i ++){
            int[] pinboardData = ArrayUtils.subarray(data, (i * pinboardAndPowerbank), 6 + (i * pinboardAndPowerbank));
            Pinboard pinboard = new Pinboard(pinboardData);
            pinboards.add(pinboard);
            List<Powerbank> powerbankList = new ArrayList<Powerbank>();

            for (int j = 0; j < hole; j++) {
                int[] powerbankData = ArrayUtils.subarray(data, (6 + (i * pinboardAndPowerbank) + (j * 15)), (21 + (i * pinboardAndPowerbank) + (j * 15)));
                Powerbank powerbank = new Powerbank(powerbankData, pinboard.getIndex());
                powerbanks.add(powerbank);
                powerbankList.add(powerbank);
            }

            Collections.sort(powerbankList, new Comparator<Powerbank>() {
                @Override
                public int compare(Powerbank o1, Powerbank o2) {
                    return o1.getIndex() - o2.getIndex();
                }
            });
            pinboard.setPowerbanks(powerbankList);
            pinboard.setSerialPort(0);
            if(pinboard.getIndex()>80)pinboard.setSerialPort(1);
        }

        Collections.sort(powerbanks, new Comparator<Powerbank>() {
            @Override
            public int compare(Powerbank o1, Powerbank o2) {
                return o1.getIndex() - o2.getIndex();
            }
        });

        Map<Integer,List<Pinboard>> listMap = pinboards.stream().collect(Collectors.groupingBy(Pinboard::getSerialPort));
        /**
         * 串口列表
         */
        for(Integer serialPorts:listMap.keySet()){
            SerialPort serialPort= new SerialPort();
            serialPort.setIndex(serialPorts);
            serialPort.setPinboards(listMap.get(serialPorts));
            serialPortList.add(serialPort);
        }
    }

    /**
     * 获取机芯孔位数量
     * @return
     */
    public int getHole() {
        return ReceiveUpload.getHole(getBytes());
    }

    /**
     * 获取机芯孔位数量
     * @return
     */
    public static int getHole(byte[] bytes) {
        //排除头部4字节，尾部校验1字节
        float size = bytes.length - 5;

        //机芯公共字节6  孔位字节15
        Float pinboard = size / (6 + 15 * 2);   //机芯数量

        //单机芯（2口）
        if (pinboard == 1) {
            return 2;
        }

        //多机芯（5口）
        pinboard = size / (6 + 15 * 5);
        if (pinboard % pinboard.intValue() == 0) {
            return 5;
        }

        //多机芯（6口）
        pinboard = size / (6 + 15 * 6);
        if (pinboard % pinboard.intValue() == 0) {
            return 6;
        }

        //多机芯（8口）
        pinboard = size / (6 + 15 * 8);
        if (pinboard % pinboard.intValue() == 0) {
            return 8;
        }

        return 0;
    }



    /**
     * 至少电量
     * @param limitPower
     * @return
     */
    public List<Powerbank> getPowerbanksByPower(int limitPower){
        List<Powerbank> data = new ArrayList<Powerbank>();
        for(Powerbank item : powerbanks){
            if(item.getSnAsInt() > 0 &&  item.getStatus() == 0X01 && item.getPower() >= limitPower && item.getPower() <= 100){
                data.add(item);
            }
        }
        return data;
    }

    public Powerbank getRandomPowerbankByPower(int limitPower){
        List<Powerbank> data = getPowerbanksByPower(limitPower);
        if(data.size() == 0){
            return null;
        }
        else if(data.size() == 1){
            return data.get(0);
        }
        else{
            int index = RandomUtils.nextInt(0, data.size());
            return data.get(index);
        }
    }

}
